import { _decorator, assetManager, Component } from 'cc';

export class ResMgr extends Component {
    private totalAb: number = 0;
    private nowAb: number = 0;

    private total: number = 0;
    private now: number = 0;

    private abBundle: any = {};
    private progressFunc: Function = null!;
    private endFunc: Function = null!;

    public static Instance: ResMgr = null!;

    protected onLoad(): void {
        if (!ResMgr.Instance) {
            ResMgr.Instance = this;
        }
        else {
            this.destroy();
            return;
        }
    }

    private loadAssetsBundle(abName: string, endFunc: Function) {
        assetManager.loadBundle(abName, (err: Error, bundle: any) => {
            if (err) {
                console.error(err);
                this.abBundle[abName] = null;
                return;
            }
            this.abBundle[abName] = bundle;
            if (endFunc) {
                endFunc(bundle);
            }
        });
    }

    private loadres(abBundle: any, url: any, typeClass: string) {
        abBundle.load(url, typeClass, (err: Error, asset: any) => {
            this.now++;
            if (err) {
                console.error(err);
                return;
            }
            if (this.progressFunc) {
                this.progressFunc(this.now, this.total);
            }
            if (this.now >= this.total) {
                if (this.endFunc)
                    this.endFunc();
            }
        });
    }


    public getAsset(abBundle: string, resUrl: string): any {
        let bundle = assetManager.getBundle(abBundle);
        if (!bundle) {
            console.error(`can not find bundle ${abBundle}`);
            return null;
        }
        let res = bundle.get(resUrl);
        if (!res) {
            console.error(`can not find res ${resUrl} in bundle ${abBundle}`);
            return null;
        }
        return res;
    }

    public releaseResPackage(respkg: any) {
        for (let key in respkg) {
            let urlSet = respkg[key].urls;
            for (var i = 0; i < urlSet.length; i++) {
                let bundle: any = assetManager.getBundle(key);
                if (bundle === null) {
                    continue;
                }
                assetManager.releaseAsset(bundle.get(urlSet[i]));
            }
        }
    }

    private loadAssetsInAssetsBundle(respkg: any) {
        for (let key in respkg) {
            let urlSet = respkg[key].urls;
            let typeClass = respkg[key].typeClass;
            for (var i = 0; i < urlSet.length; i++) {
                this.loadres(this.abBundle[key], urlSet[i], typeClass,)
            }
        }
    }

    public preloadResPackage(respkg: any, progressFunc: Function, endFunc: Function) {
        this.total = 0;
        this.now = 0;
        this.totalAb = 0;
        this.nowAb = 0;
        this.progressFunc = progressFunc;
        this.endFunc = endFunc;

        for (let key in respkg) {
            let urlSet = respkg[key].urls;
            this.total += urlSet.length;
            this.totalAb++;
        }
        for (let key in respkg) {
            this.loadAssetsBundle(key, () => {
                this.nowAb++;
                if (this.nowAb === this.totalAb) {
                    this.loadAssetsInAssetsBundle(respkg);
                }
            });
        }
    }

}


